dpdk-19.11 armv8 l2fwd 在某 arm 内核上无法运行问题
问题描述
编译 dpdk-19.11 arm 版本的 l2fwd,在指定的 arm 内核上运行,有如下报错信息:
EAL: Detected 16 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: Probing VFIO support...
EAL: error allocating rte services array
EAL: FATAL: rte_service_init() failed
EAL: rte_service_init() failed
EAL: Error - exiting with code: 1
Cause: Invalid EAL arguments
关键报错:
EAL: error allocating rte services array
确认问题
- hugepage 正常配置,hugetlbfs 正常挂载
- dpdk-16.04 的 l2fwd 能够正常运行
查看代码确认问题为在创建 rte services 数组的时候申请内存失败!
strace 跟踪获取到的结果
strace 跟踪 l2fwd 程序执行,摘录如下关键过程:
openat(AT_FDCWD, "/dev/hugepages", O_RDONLY) = 23
flock(23, LOCK_EX) = 0
openat(AT_FDCWD, "/dev/hugepages/rtemap_0", O_RDWR|O_CREAT, 0600) = 24
flock(24, LOCK_SH|LOCK_NB) = 0
ftruncate(24, 2097152) = 0
mmap(0x100200000, 2097152, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED|MAP_POPULATE, 24, 0) = 0x100200000
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
openat(AT_FDCWD, "/proc/self/pagemap", O_RDONLY) = 25
lseek(25, 8392704, SEEK_SET) = 8392704
read(25, "\0\0z\0\0\0\0\241", 8) = 8
close(25) = 0
get_mempolicy(0x7fffffce24, NULL, 0, 0x100200000, MPOL_F_NODE|MPOL_F_ADDR) = -1 ENOSYS (Function not implemented)
munmap(0x100200000, 2097152) = 0
mmap(0x100200000, 2097152, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x100200000
flock(24, LOCK_EX|LOCK_NB) = 0
unlinkat(AT_FDCWD, "/dev/hugepages/rtemap_0", 0) = 0
close(24) = 0
上述系统调用在映射第一个大页,明显的异常内容如下:
get_mempolicy(0x7fffffce24, NULL, 0, 0x100200000, MPOL_F_NODE|MPOL_F_ADDR) = -1 ENOSYS (Function not implemented)
此信息表明当前内核不支持 get_mempolicy 系统调用。
提问环节
get_mempolicy 在哪里被调用?
阅读代码确认在映射大页的过程中会调用 get_mempolicy,当失败后会使用默认值。
是否有配置关闭相关逻辑? CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES 能够用来控制这部分代码逻辑。
get_mempolicy 调用失败为什么不退出? 调用失败后会使用缺省值!
get_mempolicy 是干嘛的?
man get_mempolicy 的部分信息如下:
GET_MEMPOLICY(2) Linux Programmer's Manual GET_MEMPOLICY(2)
NAME
get_mempolicy - retrieve NUMA memory policy for a thread
SYNOPSIS
#include <numaif.h>
long get_mempolicy(int *mode, unsigned long *nodemask,
unsigned long maxnode, void *addr,
unsigned long flags);
Link with -lnuma.
解决方法
armv8 的 .config 文件中关闭 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES 配置后重新编译,测试正常。
关闭 RTE_EAL_NUMA_AWARE_HUGEPAGES 的合理性
NUMA_AWARE_HUGEPAGES 的修改能够从 [dpdk-dev] [PATCH v7 1/2] mem: balanced allocation of hugepages 中找到。
浏览 patch 内容,获取到如下信息:
diff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc
index 9f32766..2c67cdc 100644
--- a/config/defconfig_arm64-armv8a-linuxapp-gcc
+++ b/config/defconfig_arm64-armv8a-linuxapp-gcc
@@ -47,6 +47,9 @@ CONFIG_RTE_TOOLCHAIN_GCC=y
# to address minimum DMA alignment across all arm64 implementations.
CONFIG_RTE_CACHE_LINE_SIZE=128
+# Most ARMv8 systems doesn't support NUMA
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
+
大部分 ARMv8 系统并不支持 numa,缺省配置关闭。.config 中同步 ARMv8 的默认配置是合理的!